package com.freexiaoyu.freevideoplay;

import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;

public class ExoPlayerTwoActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private static final String TAG = "VideoReceiver";
    private DatagramSocket socket;
    private Thread udpReceiveThread;
    private MediaCodec mediaCodec;
    private SurfaceHolder surfaceHolder;
    private boolean isDecodingStarted = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_play);

        SurfaceView surfaceView = findViewById(R.id.surfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startReceivingUdpPackets();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stopReceivingUdpPackets();
    }

    private void startReceivingUdpPackets() {
        udpReceiveThread = new Thread(() -> {
            try {
                socket = new DatagramSocket(22001);
                byte[] buffer = new byte[1500];
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                while (!Thread.currentThread().isInterrupted()) {
                    socket.receive(packet);
                    if (!isDecodingStarted) {
                        setupMediaCodec(surfaceHolder.getSurface());
                        isDecodingStarted = true;
                    }
                    decodeFrame(packet.getData(), packet.getLength());
                }
            } catch (IOException e) {
                Log.e(TAG, "Error receiving UDP packets", e);
            } finally {
                socket.close();
            }
        });
        udpReceiveThread.start();
    }

    private void setupMediaCodec(Surface surface) throws IOException {
        mediaCodec = MediaCodec.createDecoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
        MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1080, 720); // Adjust resolution as needed
        mediaCodec.configure(mediaFormat, surface, null, 0);
        mediaCodec.start();
    }

    private void decodeFrame(byte[] data, int length) {
        ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
        ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();

        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
        if (inputBufferIndex >= 0) {
            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
            inputBuffer.clear();
            inputBuffer.put(data, 0, length);
            mediaCodec.queueInputBuffer(inputBufferIndex, 0, length, System.currentTimeMillis(), 0);
        }

        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        while (outputBufferIndex >= 0) {
            mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
        }
    }


    private void stopReceivingUdpPackets() {
        if (udpReceiveThread != null && udpReceiveThread.isAlive()) {
            udpReceiveThread.interrupt();
            try {
                udpReceiveThread.join();
            } catch (InterruptedException e) {
                Log.e(TAG, "Error joining thread", e);
            }
        }
        releaseMediaCodec();
    }

    private void releaseMediaCodec() {
        if (mediaCodec != null) {
            mediaCodec.stop();
            mediaCodec.release();
            mediaCodec = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopReceivingUdpPackets();
    }
}



